namespace SubSonic
{
    using Microsoft.VisualBasic;
    using SubSonic.Utilities;
    using System;
    using System.CodeDom.Compiler;
    using System.Data;

    public class VBCodeLanguage : ICodeLanguage
    {
        private readonly string[] keywords = new string[] { 
            "alias", "addHandler", "ansi", "as", "assembly", "auto", "binary", "byref", "byval", "case", "catch", "class", "custom", "date", "datetime", "default", 
            "directcast", "each", "else", "elseif", "end", "error", "false", "finally", "for", "friend", "global", "handles", "implements", "in", "is", "lib", 
            "loop", "me", "module", "mustinherit", "mustoverride", "mybase", "myclass", "narrowing", "new", "next", "nothing", "notinheritable", "notoverridable", "of", "off", "on", 
            "option", "optional", "overloads", "overridable", "overrides", "paramarray", "partial", "preserve", "private", "property", "protected", "public", "raiseevent", "readonly", "resume", "shadows", 
            "shared", "static", "step", "structure", "text", "then", "to", "true", "trycast", "unicode", "until", "when", "while", "widening", "withevents", "writeonly", 
            "compare", "explicit", "isfalse", "istrue", "mid", "strict"
         };

        public CodeDomProvider CreateCodeProvider()
        {
            return new VBCodeProvider();
        }

        private static string GetDefaultValue(string colName, DbType dbType)
        {
            if (Utility.IsLogicalDeleteColumn(colName))
            {
                return "False";
            }
            switch (dbType)
            {
                case DbType.AnsiString:
                case DbType.String:
                case DbType.AnsiStringFixedLength:
                case DbType.StringFixedLength:
                    return "Nothing";

                case DbType.Binary:
                    return "Nothing";

                case DbType.Boolean:
                    return "False";

                case DbType.Date:
                case DbType.DateTime:
                    return "New Date(1900,01,01)";

                case DbType.Guid:
                    return "Guid.Empty";

                case DbType.Xml:
                    return "";
            }
            return "0";
        }

        public string GetDefaultValue(string colName, DbType dbType, bool isNullableColumn)
        {
            string defaultValue = GetDefaultValue(colName, dbType);
            if (isNullableColumn && Utility.IsNullableDbType(dbType))
            {
                defaultValue = string.Format("Nullable(Of {0})", defaultValue);
            }
            return defaultValue;
        }

        public string GetUsingStatements(string[] namespaces)
        {
            string str = "";
            foreach (string str2 in namespaces)
            {
                str = str + "Imports " + str2 + Environment.NewLine;
            }
            return str;
        }

        private static string GetVariableType(DbType dbType)
        {
            switch (dbType)
            {
                case DbType.AnsiString:
                case DbType.String:
                case DbType.AnsiStringFixedLength:
                case DbType.StringFixedLength:
                    return "String";

                case DbType.Binary:
                    return "Byte()";

                case DbType.Byte:
                    return "Byte";

                case DbType.Boolean:
                    return "Boolean";

                case DbType.Currency:
                case DbType.Decimal:
                case DbType.VarNumeric:
                    return "Decimal";

                case DbType.Date:
                case DbType.DateTime:
                    return "DateTime";

                case DbType.Double:
                    return "Double";

                case DbType.Guid:
                    return "Guid";

                case DbType.Int16:
                    return "Short";

                case DbType.Int32:
                    return "Integer";

                case DbType.Int64:
                    return "Long";

                case DbType.Object:
                    return "Object";

                case DbType.SByte:
                    return "SByte";

                case DbType.Single:
                    return "Single";

                case DbType.Time:
                    return "TimeSpan";

                case DbType.UInt16:
                    return "UShort";

                case DbType.UInt32:
                    return "UInteger";

                case DbType.UInt64:
                    return "ULong";
            }
            return "String";
        }

        public string GetVariableType(DbType dbType, bool isNullableColumn)
        {
            string variableType = GetVariableType(dbType);
            if (isNullableColumn && Utility.IsNullableDbType(dbType))
            {
                variableType = string.Format("Nullable(Of {0})", variableType);
            }
            return variableType;
        }

        public bool IsKeyword(string word)
        {
            return (Array.IndexOf<string>(this.keywords, word.ToLower()) != -1);
        }

        public string CodeProvider
        {
            get
            {
                return "VBCodeProvider";
            }
        }

        public string DefaultUsingStatements
        {
            get
            {
                return "Imports System \r\nImports System.Text \r\nImports System.Data\r\nImports System.Data.SqlClient\r\nImports System.Data.Common\r\nImports System.Collections\r\nImports System.Collections.Generic\r\nImports System.ComponentModel\r\nImports System.Configuration \r\nImports System.Xml \r\nImports System.Xml.Serialization\r\nImports SubSonic \r\nImports SubSonic.Utilities\r\n";
            }
        }

        public string FileExtension
        {
            get
            {
                return ".vb";
            }
        }

        public string Identifier
        {
            get
            {
                return "VB";
            }
        }

        public string ShortName
        {
            get
            {
                return "vb";
            }
        }

        public string TemplatePrefix
        {
            get
            {
                return "VB_";
            }
        }
    }
}

